home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #2
/
Monster Media No. 2 (Monster Media)(1994).ISO
/
modem
/
wsftp2.zip
/
WS_MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-03
|
47KB
|
1,431 lines
/***************************************************************************
Windows Sockets FTP Client Application
Written by:
John A. Junod Internet: <junodj@gordon-emh2.army.mil>
267 Hillwood Street <zj8549@trotter.usma.edu>
Martinez, GA 30907 Compuserve: 72321,366
This program executable and all source code is released into the public
domain. It would be nice (but is not required) to give me a little
credit for any use of this code.
The user interface for this FTP client is designed with the novice FTP user
in mind. Usage should (??) be obvious with the possible exception of the
the transfer mode; ascii, binary or l8. All controls are standard Windows
controls.
My development and testing was all completed at home on two 386 PC's using
the Trumpet Windows Sockets DLL Alpha 15 with NCSA Telnet and WinQVT/Net 2.6
and 3.9 as the remote host. Source code may be compiled with Borland C++
in large mode.
Some code concepts and names are based on code that is copyright by the
Regents of the University of California or code published in UNIX Network
Programming by W. Richard Stevens or code in WATTCP or other public sources.
The rest is based on my knowledge of Windows programming and my
interpretation of RFC 969 and the Windows Sockets API version 1.1.
THE INFORMATION AND CODE PROVIDED IS PROVIDED AS IS WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. IN NO EVENT SHALL JOHN A. JUNOD BE LIABLE FOR ANY DAMAGES
WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS
OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF JOHN A. JUNOD HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*****************************************************************************/
// modified extensively by l kahn for windows nt and multi threading
//----------------------
#include "ws_glob.h"
#include "WS_ftp.H"
#include "version.h"
//----------------------
#include <stdarg.h>
#include <ctype.h>
#include <shellapi.h>
#include <stdlib.h>
// lgk new debugging variable
BOOLEAN DEBUGGING_ON = FALSE;
int selects[256];
extern char szInitDir[];
HBRUSH hbrGray1,hbrGray2,hbrWhite;
extern HWND hWndDbg;
BOOLEAN connectpending = FALSE;
// lgk new stuff for multiple threads
extern int check_command_line();
CRITICAL_SECTION busy_variable;
BOOLEAN busy = FALSE;
HWND globalhWnd;
WPARAM globalwParam;
DWORD threadid;
HANDLE threadhandle;
#ifndef USEASYNC
SubProcessAsync(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
return(FALSE);
}
#endif
// lgk new routine to get the local search string
extern char *localsearchstring();
int VerifyDelete(LPSTR fname)
{
wsprintf(szDlgPrompt,"Are you sure you want to delete \"%s\"?",fname);
return(MessageBox(hWndMain,szDlgPrompt,"Verify Deletion",MB_YESNO)==IDYES);
}
void MakeLower(LPSTR str) {
while(*str) {
*str=tolower(*str);
str++;
}
}
// lgk function to set busy variable so that we don't get collisions
void set_busy(invalue)
BOOLEAN invalue;
{
EnterCriticalSection(&busy_variable);
busy = invalue;
LeaveCriticalSection(&busy_variable);
}
BOOLEAN check_busy()
{
BOOLEAN rvalue;
EnterCriticalSection(&busy_variable);
rvalue = busy;
LeaveCriticalSection(&busy_variable);
return rvalue;
}
/* ------------------------------------------------------------------------------------------- */
// lgk new functions that will run in a thread
DWORD local_to_remote_fx()
{
int nIndex,nRC;
u_char tmp[80];
char localname[220];
char remotename[80];
int count;
count=SendMessage(hLbxLFiles,
LB_GETSELITEMS,256,(LPARAM)(int far *)selects);
if(count>0 && count!=LB_ERR)
{
EnableWindow(hBtnAbort,TRUE);
for(nIndex=0;nIndex<count;nIndex++)
{
SendMessage(hLbxLFiles,LB_GETTEXT,selects[nIndex],
(LONG)localname);
lstrcpy(remotename,localname);
if(bInteractive)
StdInput(remotename,"Enter remote file name for %s:",localname);
wsprintf(tmp,"sending %s as %s (%u of %u)",localname,remotename,nIndex+1,count);
SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)tmp);
wsprintf(tmp,"STOR %s",remotename);
nRC=SendFile(ctrl_socket,tmp,localname,fType);
if(nRC!=2) break;
}
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* -------------------------------------------------------------- */
DWORD remote_mkdir_fx()
{
int nRC;
if(StdInput(NULL,"Enter new remote directory name:"))
if((nRC=DoMKD(ctrl_socket,szDlgEdit))==FTP_COMPLETE)
{
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ---------------------------------------- */
DWORD remote_rmdir_fx()
{
int nIndex,nRC;
if((nIndex=SendMessage(hLbxRDir,LB_GETCURSEL,0,0L))!=LB_ERR)
{
SendMessage(hLbxRDir,LB_GETTEXT,nIndex,(LONG)szMsgBuf2);
if(VerifyDelete(szMsgBuf2))
if((nRC=DoRMD(ctrl_socket,szMsgBuf2))==FTP_COMPLETE)
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ------------------------------------------------- */
DWORD remote_list_fx()
{
GetRemoteDirForWnd(globalhWnd);
EnableWindow(hBtnAbort,TRUE);
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ----------------------------- */
DWORD remote_delete_fx()
{
int nIndex,nRC;
int count;
count=SendMessage(hLbxRFiles,LB_GETSELITEMS,
256,(LPARAM)(int far *)selects);
if(count>0 && count!=LB_ERR)
{
for(nIndex=0;nIndex<count;nIndex++)
{
SendMessage(hLbxRFiles,LB_GETTEXT,selects[nIndex],
(LONG)szDlgEdit);
if(VerifyDelete(szDlgEdit))
nRC=DoDELE(ctrl_socket,szDlgEdit);
}
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ----------------------------------------------------------- */
DWORD remote_rename_fx()
{
int nIndex,nRC;
if((nIndex=SendMessage(hLbxRFiles,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxRFiles,LB_GETTEXT,nIndex,
(LONG)szMsgBuf2);
if(StdInput(NULL,"Enter new name for \"%s\":",szMsgBuf2))
if((nRC=command(ctrl_socket,"RNFR %s",szMsgBuf2))==FTP_CONTINUE)
if((nRC=command(ctrl_socket,"RNTO %s",szDlgEdit))==FTP_COMPLETE)
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ----------------------------------------------------------- */
DWORD remote_cwd_fx()
{
int nIndex,nRC;
if((nIndex=SendMessage(hLbxRDir,LB_GETCURSEL,0,0L))!=LB_ERR)
{
EnableWindow(hBtnAbort,TRUE);
SendMessage(hLbxRDir,LB_GETTEXT,nIndex,
(LONG)szMsgBuf2);
nRC=DoCWD(ctrl_socket,szMsgBuf2);
if(nRC==FTP_COMPLETE)
GetRemoteDirForWnd(globalhWnd);
}
else
{
if(StdInput(NULL,"Enter remote directory name:"))
if((nRC=DoCWD((SOCKET)ctrl_socket,szDlgEdit))==FTP_COMPLETE)
GetRemoteDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ----------------------------------------------------------- */
DWORD remote_to_local_fx()
{
char tmp[80];
char remotename[256];
char localname[256];
char shortname[80];
int count;
int nIndex,nRC;
count=SendMessage(hLbxRFiles,LB_GETSELITEMS,
256,(LPARAM)(int far *)selects);
if(count>0 && count!=LB_ERR)
{
EnableWindow(hBtnAbort,TRUE);
for(nIndex=0;nIndex<count;nIndex++)
{
SendMessage(hLbxRFiles,LB_GETTEXT,selects[nIndex],
(LONG)remotename);
MakeLocalName(localname,shortname,remotename);
if(bInteractive)
StdInput(localname,"Enter local file name for %s:",remotename);
DoPrintf("receiving %s as %s (%u of %u)",
remotename,localname,nIndex+1,count);
wsprintf(tmp,"RETR %s",remotename);
nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,
(LPSTR)localname,(LPSTR)shortname,fType);
if(nRC==2)
SendMessage(hLbxLFiles,LB_ADDSTRING,0,(LONG)remotename);
else
break;
} // end of loop
GetLocalDirForWnd(globalhWnd);
} // end of count ok
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* --------------------------------------------------------- */
DWORD remote_display_fx()
{
int nIndex,nRC;
char tmp[80];
char remotename[80];
if((nIndex=SendMessage(hLbxRFiles,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxRFiles,LB_GETTEXT,nIndex,
(LONG)remotename);
wsprintf(tmp,"RETR %s",remotename);
EnableWindow(hBtnAbort,TRUE);
nRC=RetrieveFile((SOCKET)ctrl_socket,(LPSTR)tmp,
(LPSTR)szTmp1File,(LPSTR)szTmp1File,TYPE_A);
if(nRC==2)
{
wsprintf(szString,"%s %s",szViewer,szTmp1File);
if(strchr(szTmp1File,'.')==NULL)
strcat(szString,".");
WinExec(szString,SW_SHOW);
}
GetLocalDirForWnd(globalhWnd);
}
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ----------------------------------------------------------- */
DWORD connect_fx()
{
int nRC;
connectpending = TRUE;
if(ctrl_socket==INVALID_SOCKET)
{
EnableWindow(hBtnConnect,FALSE);
use_gateway=0;
nRC=DialogBox(hInst,(LPSTR)"DLG_HOST",globalhWnd,WS_HostMsgProc);
if(nRC)
{
EnableWindow(hBtnAbort,TRUE);
ctrl_socket=(SOCKET)DoConnect(szRemoteHost);
if(ctrl_socket!=INVALID_SOCKET)
{
if(szInitDir[0]!=0)
DoCWD(ctrl_socket,szInitDir);
}
else // didn't connect so renable button
EnableWindow(hBtnConnect,TRUE);
if(LOWORD(globalwParam)==BTN_CONNECT)
GetRemoteDirForWnd(globalhWnd);
} // ok nrc
}
else
SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)"Already connected");
set_busy(FALSE);
connectpending = FALSE;
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* ---------------------------------------------------------- */
DWORD drop_files_fx()
{
int nRC;
POINT pt;
WORD cFiles, a;
char szFile[256];
char szRemoteName[256];
u_char tmp[256];
LPSTR lpszBaseName;
DragQueryPoint((HANDLE) globalwParam, &pt);
cFiles = DragQueryFile((HANDLE) globalwParam, 0xFFFF, (LPSTR) NULL, 0);
if(!bConnected)
DoPrintf("NOT CONNECTED!! File(s) ignored.");
else if(bCmdInProgress)
DoPrintf("We are already busy!! File(s) ignored.");
else
{
for(a = 0; a < cFiles; pt.y += 20, a++)
{
DragQueryFile((HANDLE) globalwParam, a, szFile, sizeof(szFile));
MakeLower(szFile);
if((lpszBaseName=strrchr(szFile,'\\'))!=NULL)
{
lstrcpy(szRemoteName,++lpszBaseName);
if(bInteractive)
StdInput(szRemoteName,"Enter remote file name for %s:",lpszBaseName);
EnableWindow(hBtnAbort,TRUE);
wsprintf(tmp,"sending %s as %s (%u of %u)",szFile,szRemoteName,a,cFiles);
SendMessage(hTxtStatus,WM_SETTEXT,0,(LPARAM)tmp);
wsprintf(tmp,"STOR %s",szRemoteName);
nRC=SendFile(ctrl_socket,tmp,szFile,fType);
if(nRC!=2) break;
}
} // end of loop
GetRemoteDirForWnd(globalhWnd);
} // end ok case
DragFinish((HANDLE) globalwParam);
set_busy(FALSE);
EnableWindow(hBtnAbort,FALSE);
return 0;
}
/* -------------------------------------------- */
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
int nRc;
long nWndunits;
int nX;
int nY;
int nWidth;
int nHeight;
int err;
// HINSTANCE hWinSock;
InitializeCriticalSection(&busy_variable);
if (strstr(lpszCmdLine,"-d") != NULL)
{
// we want debugging
DEBUGGING_ON = TRUE;
}
if ((err = WSAStartup((WORD)0x0101, &WSAData))!=0) // register task with
{ // winsock tcp/ip API
MessageBox(NULL,ReturnWSError(err,NULL),"WS_FTP - WSAStartup",
MB_OK|MB_ICONEXCLAMATION);
} else {
strcpy(szAppName, "WS_FTP");
hInst = hInstance;
if(!hPrevInstance)
{
// register window classes if first instance of application
if ((nRc = nCwRegisterClasses()) == -1)
{
// registering one of the windows failed
MessageBox((HWND)NULL, "Window creation failed",
NULL, MB_ICONEXCLAMATION);
return nRc;
}
}
// Create a device independant size and location
nWndunits = GetDialogBaseUnits();
nWndx = LOWORD(nWndunits);
nWndy = HIWORD(nWndunits);
nX = ((18 * nWndx) / 4);
nY = ((18 * nWndy) / 8);
nWidth = ((247 * nWndx) / 4);
nHeight = ((211 * nWndy) / 8);
// create application's Main window
hWndMain = CreateWindow(
szAppName, "WinSock_FTP",
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
WS_CLIPCHILDREN | WS_OVERLAPPED,
nX,nY, nWidth, nHeight,
(HWND)NULL, (HMENU)NULL, hInst, NULL);
if(hWndMain == (HWND)NULL)
{
MessageBox((HWND)NULL, "Error registering class",
NULL, MB_ICONEXCLAMATION);
return 2;
}
ShowWindow(hWndMain, nCmdShow); // display main window
GetLocalInfo();
if(bAutoStart)
PostMessage(hWndMain,WM_COMMAND,BTN_CONNECT,0L);
// lgk now check if command line stuff
if (check_command_line() == 1)
{
// use to exit here when not multi-threaded but now returns immediately
}
while(GetMessage(&msg, (HWND)NULL, 0, 0)) // Until WM_QUIT message
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
WSACleanup();
ReleaseDisplayMem();
// Do clean up before exiting from the application
CwUnRegisterClasses();
}
return msg.wParam;
} // End of WinMain
int StdInput(LPSTR dest,LPSTR fmt,...)
{
va_list args;
// FARPROC lpfnMsgProc;
int iRetCode;
va_start(args,fmt);
vsprintf(szDlgPrompt,fmt,args);
va_end(args);
if (dest != NULL) // lgk fix for nt caused access violation
lstrcpy(szDlgEdit,dest);
else szDlgEdit[0] = 0;
// lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
iRetCode=DialogBox(hInst,(LPSTR)"DLG_INPUT",hWndMain,WS_InputMsgProc);
// FreeProcInstance(lpfnMsgProc);
if(iRetCode && dest)
// lgk fix here since if dest was null we cannot copy to it
if (dest != NULL)
lstrcpy(dest,szDlgEdit);
return(iRetCode);
}
int StdInputPassword(LPSTR dest,LPSTR fmt,...)
{
va_list args;
//FARPROC lpfnMsgProc;
int iRetCode;
va_start(args,fmt);
vsprintf(szDlgPrompt,fmt,args);
va_end(args);
lstrcpy(szDlgEdit,dest);
// lpfnMsgProc=MakeProcInstance((FARPROC)WS_InputMsgProc,hInst);
iRetCode=DialogBox(hInst,(LPSTR)"DLG_INPUT_PASSWORD",hWndMain,WS_InputMsgProc);
// FreeProcInstance(lpfnMsgProc);
if(iRetCode && dest) lstrcpy(dest,szDlgEdit);
return(iRetCode);
}
/************************************************************************/
/* Main Window Procedure */
/************************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)
{
int nIndex; //,nRC;
char tempdirectoryname[256];
switch (Message)
{
/* case WM_KEYDOWN:
// carriage return hit see which window is active
if (wParam == VK_RETURN)
{
HWND activewind = GetActiveWindow();
if (activewind == hLdirBox)
{
GetLocalDirForWnd(hWnd);
}
else
if (activewind == hRdirBox)
{
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote list fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_list_fx,NULL,0,&threadid);
}
}
}
break;
*/
case WM_COMMAND:
if(LOWORD(wParam)==BTN_CLOSE || LOWORD(wParam)==BTN_EXIT ||
LOWORD(wParam)==CMD_CLOSE || LOWORD(wParam)==IDM_EXIT)
{
bAborted=TRUE;
// kill remote thread first
if (check_busy())
{
DoAddLine("Aborting thread before closing/exiting\n");
TerminateThread(threadhandle,1);
set_busy(FALSE);
}
if(data_socket!=INVALID_SOCKET)
data_socket=DoClose(data_socket);
if(listen_socket!=INVALID_SOCKET)
listen_socket=DoClose(listen_socket);
if(ctrl_socket!=INVALID_SOCKET)
{
command(ctrl_socket,"QUIT");
ctrl_socket=DoClose(ctrl_socket);
bConnected=FALSE;
}
SetWindowText(hWnd,"WS_FTP32");
if(LOWORD(wParam)==IDM_EXIT || LOWORD(wParam)==BTN_EXIT)
SendMessage(hWnd,WM_CLOSE,0,0L);
else
{ // close not exit so enable windows correctly
EnableWindow(hBtnConnect,TRUE);
EnableWindow(hBtnAbort,FALSE);
EnableWindow(hBtnClose,FALSE);
GetRemoteDirForWnd(hWnd);
}
break;
} //else if ((bCmdInProgress) return(FALSE);
switch (LOWORD(wParam))
{
// child windows messages ************************************
// local buttons and boxes
// lgk new case for abort
case BTN_ABORT:
// kill remote thread first
// problem here if we abort during a connect we also need to close the control socket
// check this via the connect flag
// since we cant get this to work correctly disable it for now
DoPrintf("Abort is Not Yet Implemented Due to problems.\n");
/*
if (check_busy())
{
DoPrintf("Aborting Remote thread\n");
TerminateThread(threadhandle,1);
set_busy(FALSE);
if(data_socket!=INVALID_SOCKET)
{
// shutdown(data_socket,2);
data_socket=DoClose(data_socket);
}
bAborted=TRUE;
bCmdInProgress = 0;
if(listen_socket!=INVALID_SOCKET)
listen_socket=DoClose(listen_socket);
bCmdInProgress = 0;
if (connectpending)
{
int err = 0;
if (ctrl_socket!=INVALID_SOCKET)
{
command(ctrl_socket,"QUIT");
ctrl_socket = DoClose(ctrl_socket);
}
bConnected = FALSE;
DoPrintf("Remote Connect Aborted\n");
connectpending = FALSE;
bCmdInProgress = 0;
EnableWindow(hBtnConnect,TRUE);
EnableWindow(hBtnAbort,FALSE);
EnableWindow(hBtnClose,FALSE);
SetWindowText(hWnd,"WS_FTP32");
// bug in winsock after closing does not work correctly
}
else DoPrintf("Remote Operation Aborted\n");
} */
break;
// lgk new case for changing txt in directory search routine
case TXT_LDIRSEL:
{
// check if carriage return
char *temp = localsearchstring();
// if (HIWORD(wParam) == EN_CHANGE)
// DoPrintf("temp is %s \n",temp);
if ((HIWORD(wParam) == EN_KILLFOCUS) && SendMessage(hLdirBox,EM_GETMODIFY,0,0))
{
GetLocalDirForWnd(hWnd);
}
// bug in redraw so force it
if (HIWORD(wParam) == EN_UPDATE)
{
SendMessage(hLdirBox,WM_SETFONT,0,MAKELPARAM(TRUE,0));
}
}
break;
case LST_LDIRS:
if (HIWORD(wParam) !=LBN_DBLCLK) return(FALSE);
case BTN_LCHANGE:
if((nIndex=SendMessage(hLbxLDir,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxLDir,LB_GETTEXT,nIndex,
(LONG)szMsgBuf2);
if(strncmp(szMsgBuf2,"[-",2)==0) {
#ifdef _MSC_
_chdrive(tolower(szMsgBuf2[2])-0x60);
#else
setdisk(szMsgBuf2[2]-'a');
#endif
GetLocalDirForWnd(hWnd);
} else if(chdir(szMsgBuf2)==0)
GetLocalDirForWnd(hWnd);
} else
{
if(StdInput(NULL,"Enter local directory name:")) {
if(szDlgEdit[1]==':')
#ifdef _MSC_
_chdrive(tolower(szDlgEdit[0])-0x60);
#else
setdisk(tolower(szDlgEdit[0])-'a');
#endif
chdir(szDlgEdit);
GetLocalDirForWnd(hWnd);
}
}
break;
case LST_LFILES:
if(HIWORD(wParam) !=LBN_DBLCLK) return(FALSE);
case BTN_LOCAL_TO_REMOTE:
{
globalhWnd = hWnd;
globalwParam = wParam;
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create and call button to remote thread here
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)local_to_remote_fx,NULL,0,&threadid);
} // end of not busy
} // end of btn local to remote
break;
// lgk allow local commands while remote are running
case BTN_LMKDIR:
if(StdInput(NULL,"Enter new local directory name:")) {
mkdir(szDlgEdit);
GetLocalDirForWnd(hWnd);
}
break;
case BTN_LRMDIR:
if((nIndex=SendMessage(hLbxLDir,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxLDir,LB_GETTEXT,nIndex,
(LONG)szMsgBuf2);
if(VerifyDelete(szMsgBuf2))
if(rmdir(szMsgBuf2)==0)
GetLocalDirForWnd(hWnd);
}
break;
case BTN_LDELETE:
{
int count;
count=SendMessage(hLbxLFiles,
LB_GETSELITEMS,256,(LPARAM)(int far *)selects);
if(count>0 && count!=LB_ERR) {
for(nIndex=0;nIndex<count;nIndex++) {
SendMessage(hLbxLFiles,LB_GETTEXT,selects[nIndex],
(LONG)szDlgEdit);
if(VerifyDelete(szDlgEdit))
unlink(szDlgEdit);
}
GetLocalDirForWnd(hWnd);
}
}
break;
case BTN_LRENAME:
if((nIndex=SendMessage(hLbxLFiles,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxLFiles,LB_GETTEXT,nIndex,
(LONG)szMsgBuf2);
if(StdInput(NULL,"Enter new name for \"%s\":",szMsgBuf2))
if(rename(szMsgBuf2,szDlgEdit)==0)
GetLocalDirForWnd(hWnd);
}
break;
case BTN_LDISPLAY:
{
char remotename[80];
if((nIndex=SendMessage(hLbxLFiles,LB_GETCURSEL,
0,0L))!=LB_ERR)
{
SendMessage(hLbxLFiles,LB_GETTEXT,nIndex,
(LONG)remotename);
wsprintf(szMsgBuf2,"%s %s",szViewer,remotename);
if(strchr(remotename,'.')==NULL)
strcat(szMsgBuf2,".");
WinExec(szMsgBuf2,SW_SHOW);
}
}
break;
// remote buttons and boxes
case BTN_RMKDIR:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_mkdir_fx,NULL,0,&threadid);
// create thread and start remote makedir fx
}
break;
case BTN_RRMDIR:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote remove dir fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_rmdir_fx,NULL,0,&threadid);
}
break;
case BTN_RDELETE:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote delete fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_delete_fx,NULL,0,&threadid);
}
break;
case BTN_RRENAME:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote rename fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_rename_fx,NULL,0,&threadid);
}
break;
// lgk new case for changing txt in directory search routine
case TXT_RDIRSEL:
// bug in redraw so force it
if (HIWORD(wParam) == EN_UPDATE)
{
SendMessage(hRdirBox,WM_SETFONT,0,MAKELPARAM(TRUE,0));
}
if ((HIWORD(wParam) == EN_KILLFOCUS) && SendMessage(hRdirBox,EM_GETMODIFY,0,0))
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote list fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_list_fx,NULL,0,&threadid);
}
break;
case LST_RDIRS:
if(HIWORD(wParam)!=LBN_DBLCLK) return(FALSE);
case BTN_RCHANGE:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote cwd fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_cwd_fx,NULL,0,&threadid);
}
break;
case LST_RFILES:
if(HIWORD(wParam)!=LBN_DBLCLK) return(FALSE);
case BTN_REMOTE_TO_LOCAL:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote to local fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_to_local_fx,NULL,0,&threadid);
}
break;
case BTN_RDISPLAY:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start remote display fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)remote_display_fx,NULL,0,&threadid);
}
break;
case RB_ASCII:
fType=TYPE_A;
ShowType:
case RB_SHOWCHECKS:
SendMessage(hRBascii, BM_SETCHECK,fType==TYPE_A,0L);
SendMessage(hRBbinary,BM_SETCHECK,fType==TYPE_I,0L);
SendMessage(hRBl8, BM_SETCHECK,fType==TYPE_L,0L);
break;
case RB_BINARY:
fType=TYPE_I;
goto ShowType;
case RB_L8:
fType=TYPE_L;
goto ShowType;
// end of child window message processing *******************
case BTN_CONNECT:
case CMD_CONNECT:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start connect fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)connect_fx,NULL,0,&threadid);
}
break;
case BTN_LONG:
if(bConnected) {
wsprintf(szMsgBuf2,"%s %s",szViewer,szTmpFile);
WinExec(szMsgBuf2,SW_SHOW);
}
break;
case BTN_OPTION:
{
//FARPROC lpfnMsgProc;
// lpfnMsgProc = MakeProcInstance((FARPROC)WS_StatMsgProc, hInst);
DialogBox(hInst, (LPSTR)"DLG_STATUS", hWnd, WS_StatMsgProc);
// FreeProcInstance(lpfnMsgProc);
}
SendMessage(hWnd,WM_COMMAND,RB_SHOWCHECKS,0l);
break;
case BTN_ABOUT:
case IDM_ABOUT:
{
DialogBox(hInst, (LPSTR)"DLG_ABOUT", hWnd, WS_AboutMsgProc);
}
break;
default:
if(!SubProcessAsync(hWnd,Message,wParam,lParam))
return DefWindowProc(hWnd, Message, wParam, lParam);
}
break;
case WM_VSCROLL:
switch(LOWORD(wParam)) {
case SB_LINEUP:
ScrollStatus(-1);
break;
case SB_LINEDOWN:
ScrollStatus(1);
break;
}
break;
case WM_CREATE:
hStdCursor=LoadCursor((HINSTANCE)NULL,IDC_ARROW);
hWaitCursor=LoadCursor((HINSTANCE)NULL,IDC_WAIT);
LoadUserInfo();
hbrGray1= CreateSolidBrush(RGB(192,192,192));
hbrGray2=CreateSolidBrush(RGB(128,128,128));
hbrWhite=CreateSolidBrush(RGB(255,255,255));
if (DEBUGGING_ON)
CreateDebugWindow(hWnd,hInst);
CreateSubWindows(hWnd,hInst);
SendMessage(hLdirBox,EM_LIMITTEXT,(WPARAM)50,0);
SendMessage(hRdirBox,EM_LIMITTEXT,(WPARAM)50,0);
SendMessage(hLdirBox,WM_SETTEXT,0,(LPARAM)"");
SendMessage(hRdirBox,WM_SETTEXT,0,(LPARAM)"");
SendMessage(hLdirBox,EM_GETMODIFY,0,0);
SendMessage(hRdirBox,EM_GETMODIFY,0,0);
GetLocalDirForWnd(hWnd);
GetRemoteDirForWnd(hWnd);
SendMessage(hWnd,WM_COMMAND,RB_SHOWCHECKS,0L);
GetCurrentDirectory(140,tempdirectoryname);
GetTempFileName(tempdirectoryname,"DIR",0,szTmpFile);
GetTempFileName(tempdirectoryname,"DSP",0,szTmp1File);
DragAcceptFiles(hWnd,TRUE);
// lgk limit the text for both dir boxes and initialize them to blank
break;
// lgk timer messages do not work between threads so use a timer proc now
case WM_TIMER:
if(wParam==10)
{
KillTimer(hWndMain,10);
if(WSAIsBlocking())
{
// lgk if we are blocking in another thread here we need to kill
// it also
if (check_busy())
{
DoAddLine("Timer cancelled blocking call");
bAborted=TRUE;
WSACancelBlockingCall();
TerminateThread(threadhandle,1);
set_busy(FALSE);
}
else
{
DoAddLine("Timer cancelled blocking call");
bAborted=TRUE;
WSACancelBlockingCall();
}
}
}
break;
case WM_CTLCOLORBTN:
if(LOWORD(lParam)<10) return((LRESULT)NULL);
// lgk add suport for background color change for our edit box
case WM_CTLCOLORSTATIC:
SelectObject((HDC)wParam, GetStockObject(ANSI_VAR_FONT));
SetBkColor((HDC) wParam, RGB(192,192,192));
return(LRESULT)hbrGray1;
break;
case WM_CTLCOLOREDIT:
SelectObject((HDC)wParam, GetStockObject(ANSI_VAR_FONT));
SetBkColor((HDC) wParam, RGB(255, 255, 255));
return(LRESULT)hbrWhite;
break;
case WM_SETCURSOR:
if(bCmdInProgress) {
SetCursor(hWaitCursor);
return(TRUE);
} else
return DefWindowProc(hWnd, Message, wParam, lParam);
case WM_DROPFILES:
// lgk new code first check if busy and if so print out a message
if (check_busy())
DoPrintf("Currently Busy with another remote operation ...\n");
else
{
globalhWnd = hWnd;
globalwParam = wParam;
set_busy(TRUE);
// create thread and start dropfiles fx
threadhandle = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)drop_files_fx,NULL,0,&threadid);
}
break;
case WM_PAINT: // code for the window's client area
DoMainPaint(hWnd);
break;
case WM_CLOSE: // close the window
// Destroy child windows, modeless dialogs, then, this window
if (hWnd == hWndMain) {
if(data_socket!=INVALID_SOCKET)
data_socket=DoClose(data_socket);
if(listen_socket!=INVALID_SOCKET)
listen_socket=DoClose(data_socket);
if(ctrl_socket!=INVALID_SOCKET)
ctrl_socket=DoClose(ctrl_socket);
DestroyWindow(hWnd);
SaveUserInfo();
DeleteObject(hbrGray1);
DeleteObject(hbrGray2);
DeleteObject(hbrWhite);
_unlink(szTmpFile);
_unlink(szTmp1File);
DragAcceptFiles(hWnd,FALSE);
// lgk if we are busy here we must kill any active task
if (check_busy())
{
DoPrintf("Killing active thread ... \n");
TerminateThread(threadhandle,1);
set_busy(FALSE);
}
PostQuitMessage(0); // Quit the application
} else
DestroyWindow(hWnd);
DeleteCriticalSection(&busy_variable);
break;
default:
if(!SubProcessAsync(hWnd,Message,wParam,lParam))
return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0L;
} // End of WndProc
/************************************************************************/
/* Misc Dialog Window Procedures */
/************************************************************************/
BOOL CALLBACK WS_AboutMsgProc(HWND hWndDlg, UINT Message,
WPARAM wParam, LPARAM lParam)
{
char buf[40];
switch(Message)
{
case WM_INITDIALOG:
cwCenter(hWndDlg, 0);
wsprintf(buf,"Version %s",VERSION);
SetDlgItemText(hWndDlg,DLG_EDIT,buf);
break;
case WM_CTLCOLORBTN:
if(LOWORD(lParam)<10) return((BOOL)NULL);
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
SetBkColor((HDC) wParam, RGB(192,192,192));
return (BOOL)hbrGray1;
break;
case WM_CLOSE:
PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
EndDialog(hWndDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hWndDlg, FALSE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
BOOL CALLBACK WS_InputMsgProc(HWND hWndDlg, UINT Message,
WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
SetDlgItemText(hWndDlg,DLG_PROMPT,szDlgPrompt);
SetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit);
cwCenter(hWndDlg, 0);
break;
case WM_CTLCOLORBTN:
if(LOWORD(lParam)<10) return((LRESULT)NULL);
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
SetBkColor((HDC) wParam, RGB(192,192,192));
return(LRESULT)hbrGray1;
break;
case WM_CLOSE:
PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
GetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit,70);
EndDialog(hWndDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hWndDlg, FALSE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
BOOL CALLBACK WS_StatMsgProc(HWND hWndDlg, UINT Message,
WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
SetDlgItemText(hWndDlg,DLG_EDIT,szViewer);
SetDlgItemText(hWndDlg,DLG_MAILADDR,szMailAddress);
if(fType==TYPE_A)
CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_ASCII);
else if(fType==TYPE_I)
CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_BINARY);
else
CheckRadioButton(hWndDlg,RB_ASCII,RB_L8,RB_L8);
CheckDlgButton(hWndDlg,CKB_VERBOSE,bVerbose);
CheckDlgButton(hWndDlg,CKB_BELL,bBell);
CheckDlgButton(hWndDlg,CKB_GLOBBING,bDoGlob);
CheckDlgButton(hWndDlg,CKB_HASH,bHash);
CheckDlgButton(hWndDlg,CKB_PROMPT,bInteractive);
CheckDlgButton(hWndDlg,CKB_MCASE,bMCase);
CheckDlgButton(hWndDlg,CKB_PORT_CMDS,bSendPort);
CheckDlgButton(hWndDlg,CKB_RECV_UNIQUE,bRecvUniq);
CheckDlgButton(hWndDlg,CKB_STOR_UNIQUE,bStorUniq);
CheckDlgButton(hWndDlg,CKB_CRSTRIP,bCRstrip);
CheckDlgButton(hWndDlg,CKB_AUTOSTART,bAutoStart);
break;
case WM_CLOSE:
PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
break;
case WM_SETCURSOR:
if(bCmdInProgress)
SetCursor(hWaitCursor);
else
return FALSE;
break;
case WM_CTLCOLORBTN:
if(LOWORD(lParam)<10) return((LRESULT)NULL);
case WM_CTLCOLORDLG:
case WM_CTLCOLORSTATIC:
SetBkColor((HDC) wParam, RGB(192,192,192));
return(LRESULT)hbrGray1;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
if(IsDlgButtonChecked(hWndDlg,RB_ASCII)) fType=TYPE_A;
else if(IsDlgButtonChecked(hWndDlg,RB_BINARY)) fType=TYPE_I;
else fType=TYPE_L;
bVerbose=IsDlgButtonChecked(hWndDlg,CKB_VERBOSE);
bBell=IsDlgButtonChecked(hWndDlg,CKB_BELL);
bDoGlob=IsDlgButtonChecked(hWndDlg,CKB_GLOBBING);
bHash=IsDlgButtonChecked(hWndDlg,CKB_HASH);
bInteractive=IsDlgButtonChecked(hWndDlg,CKB_PROMPT);
bMCase=IsDlgButtonChecked(hWndDlg,CKB_MCASE);
bSendPort=IsDlgButtonChecked(hWndDlg,CKB_PORT_CMDS);
bRecvUniq=IsDlgButtonChecked(hWndDlg,CKB_RECV_UNIQUE);
bStorUniq=IsDlgButtonChecked(hWndDlg,CKB_STOR_UNIQUE);
bCRstrip=IsDlgButtonChecked(hWndDlg,CKB_CRSTRIP);
bAutoStart=IsDlgButtonChecked(hWndDlg,CKB_AUTOSTART);
GetDlgItemText(hWndDlg,DLG_EDIT,szViewer,70);
GetDlgItemText(hWndDlg,DLG_MAILADDR,szMailAddress,127);
EndDialog(hWndDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hWndDlg, FALSE);
break;
}
break; // End of WM_COMMAND
default:
return FALSE;
}
return TRUE;
}
/************************************************************************/
/* nCwRegisterClasses Function */
/* The following function registers all the classes of all the windows */
/* associated with this application. The function returns an error code */
/* if unsuccessful, otherwise it returns 0. */
/************************************************************************/
int nCwRegisterClasses(void)
{
WNDCLASS wndclass; // struct to define a window class
memset(&wndclass, 0x00, sizeof(WNDCLASS));
// load WNDCLASS with window's characteristics
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
wndclass.lpfnWndProc = WndProc;
// Extra storage for Class and Window objects
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon(hInst, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
// Create brush for erasing background
wndclass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(192,192,192));
wndclass.lpszMenuName = NULL; // szAppName; /* Menu Name is App Name */
wndclass.lpszClassName = szAppName; /* Class Name is App Name */
if(!RegisterClass(&wndclass))
return -1;
return(0);
} // End of nCwRegisterClasses
/************************************************************************/
/* cwCenter Function */
/* centers a window based on the client area of its parent */
/************************************************************************/
void cwCenter(hWnd, top)
HWND hWnd;
int top;
{
POINT pt;
RECT swp;
RECT rParent;
int iwidth;
int iheight;
// get the rectangles for the parent and the child
GetWindowRect(hWnd, &swp);
// calculate the height and width for MoveWindow
iwidth = swp.right - swp.left;
iheight = swp.bottom - swp.top;
if(IsIconic(hWndMain))
MoveWindow(hWnd, 0, 0, iwidth, iheight, FALSE);
else {
GetClientRect(hWndMain, &rParent);
// find the center point and convert to screen coordinates
pt.x = (rParent.right - rParent.left) / 2;
pt.y = (rParent.bottom - rParent.top) / 2;
ClientToScreen(hWndMain, &pt);
// calculate the new x, y starting point
pt.x = pt.x - (iwidth / 2);
pt.y = pt.y - (iheight / 2);
// top will adjust the window position, up or down
if(top)
pt.y = pt.y + top;
// move the window
MoveWindow(hWnd,max(0,pt.x),max(0,pt.y), iwidth, iheight, FALSE);
}
} // end of cwCenter
/************************************************************************/
/* CwUnRegisterClasses Function */
/* Deletes any refrences to windows resources created for this */
/* application, frees memory, deletes instance, handles and does */
/* clean up prior to exiting the window */
/************************************************************************/
void CwUnRegisterClasses(void)
{
WNDCLASS wndclass; // struct to define a window class
memset(&wndclass, 0x00, sizeof(WNDCLASS));
GetClassInfo(hInst, szAppName, &wndclass);
DeleteObject(wndclass.hbrBackground);
UnregisterClass(szAppName, hInst);
UnregisterClass(DBUGWNDCLASS,hInst);
} // End of CwUnRegisterClasses